package com.example.bluetoothapplication.bluetooth;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothSocket;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.AsyncTask;

import androidx.appcompat.app.AlertDialog;

import com.coszero.utilslibrary.utils.LogX;
import com.coszero.utilslibrary.utils.ToastUtils;

import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.UUID;

/**
 * Desc： 蓝牙开发工具类
 *
 * @author xmqian
 * Email:xmqian93@163.com
 * Date: 2020/10/27 0027 17:56
 */
public class BluetoothUtils {
    private static final String TAG = "BluetoothUtils";
    /**
     * 开启蓝牙请求码,如果需要开启回调可以使用此值在
     * onActivityResult()方法中捕捉
     */
    public static final int REQUEST_ENABLE_BT = 222;
    private String deviceName = "";
    private BluetoothAdapter adapter;
    private BluetoothSocket bluetoothSocket = null;
    private static final UUID bluetoothUUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
    private OutputStream outputStream = null;
    private InputStream inputStream = null;

    private boolean isConnection = false;
    private MessageCallback callback;
    private DeviceConnector connector;
    private BluetoothResponseHandler mHandler;
    //蓝牙状态回调
    private BluetoothReceiver stateChangeReceiver = new BluetoothReceiver();
    private static BluetoothUtils bluetoothUtils;

    public static BluetoothUtils getInstance() {
        if (bluetoothUtils == null) {
            bluetoothUtils = new BluetoothUtils();
            return bluetoothUtils;
        }
        return bluetoothUtils;
    }

    /**
     * 检查蓝牙
     * 判断蓝牙是否打开
     * 判断是否支持蓝牙
     */
    public boolean checkBluetooth(Activity activity) {
        adapter = BluetoothAdapter.getDefaultAdapter();
        //为null说明设备不支持蓝牙
        if (null != adapter) {
            //尝试打开蓝牙
            if (!adapter.isEnabled()) {
                openBluetooth(activity);
            }
            return true;
        }
        return false;
    }

    public void init() {
        if (mHandler == null) {
            mHandler = new BluetoothResponseHandler();
        }
        if (adapter == null) {
            adapter = BluetoothAdapter.getDefaultAdapter();
        }
    }

    public BluetoothAdapter getAdapter() {
        return adapter;
    }

    public BluetoothResponseHandler getmHandler() {
        return mHandler;
    }

    public void setCallback(MessageCallback callback) {
        this.callback = callback;
    }

    /**
     * 连接蓝牙
     * 如果是拼接的蓝牙地址，那就取从后到前17位
     * CharSequence address = info.toString().substring(info.length() - 17);
     **/
    @SuppressLint("StaticFieldLeak")
    public void connect(final String address) {

        new AsyncTask() {
            @Override
            protected String doInBackground(Object[] params) {

                try {
                    BluetoothDevice device = adapter.getRemoteDevice(address);
                    bluetoothSocket = device.createRfcommSocketToServiceRecord(bluetoothUUID);
                    adapter.cancelDiscovery();

                    bluetoothSocket.connect();
                    outputStream = bluetoothSocket.getOutputStream();
                    inputStream = bluetoothSocket.getInputStream();

                    while (true) {
                        byte[] data = new byte[500];
                        int count = inputStream.read(data);

                        int[] data_int = new int[data.length];
                        for (int i = 0; i < data.length; i++) {
                            data_int[i] = (byte) (data[i] & 0xff);
                        }

                        if (callback != null) {
                            callback.bluttoothMessage(data_int);
                        }
                    }
                } catch (Exception e) {
                    LogX.e(e.getMessage());
                }
                return null;
            }

            @Override
            protected void onPreExecute() {
                super.onPreExecute();
            }

            @Override
            protected void onPostExecute(Object o) {
                super.onPostExecute(o);
            }
        }.execute();
    }

    /**
     * 获取已配对的蓝牙列表
     *
     * @return Set<BluetoothDevice>
     */
    public Set<BluetoothDevice> getAlreadyPairedBluetoothDeviceList() {
        Set<BluetoothDevice> devices = null;
        if (adapter != null) {
            devices = adapter.getBondedDevices();
            if (devices.size() > 0) {
                for (Iterator<BluetoothDevice> it = devices.iterator(); it.hasNext(); ) {
                    BluetoothDevice device = it.next();
                    LogX.e(TAG, device.getName() + " " + device.getAddress());
                }
            } else {
                LogX.e(TAG, "没有已配对的蓝牙设备");
            }
        }
        return devices;
    }

    /**
     * 发送数据
     *
     * @param message
     */
    public void sendMessage(String message) {
        sendMessage(message.getBytes());
    }

    /**
     * 发送数据
     *
     * @param message
     */
    public void sendMessage(final byte[] message) {
        try {
//            outputStream.write(message);
//            outputStream = bluetoothSocket.getOutputStream();
//            inputStream = bluetoothSocket.getInputStream();
            if (isConnection) {
                new Thread(new Runnable() {
                    @Override
                    public void run() {
                        connector.write(concat(message, "\n".getBytes()));
                    }
                }).start();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static byte[] concat(byte[] A, byte[] B) {
        byte[] C = new byte[A.length + B.length];
        System.arraycopy(A, 0, C, 0, A.length);
        System.arraycopy(B, 0, C, A.length, B.length);
        return C;
    }

    /**
     * 打开蓝牙
     */
    public void openBluetooth(Activity activity) {
        if (adapter != null) {
            if (!adapter.isEnabled()) {
                Intent intent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
                activity.startActivityForResult(intent, REQUEST_ENABLE_BT);
            }
        }
    }

    /**
     * 断开蓝牙
     */
    public void disconnectBluetooth() {
//        adapter.closeProfileProxy();
    }

    /**
     * 显示蓝牙列表对话框
     */
    public void showDialog(Activity activity) {

        final Set<BluetoothDevice> bluetoothDeviceSet = getAlreadyPairedBluetoothDeviceList();
        final List<BluetoothDevice> bluetoothDeviceList = new ArrayList<BluetoothDevice>(bluetoothDeviceSet);
        final String[] items = new String[bluetoothDeviceSet.size()];

        for (int i = 0; i < bluetoothDeviceList.size(); i++) {
            items[i] = bluetoothDeviceList.get(i).getName() + " " + bluetoothDeviceList.get(i).getAddress();
        }

        AlertDialog.Builder listDialog = new AlertDialog.Builder(activity);
        listDialog.setTitle("已配对蓝牙列表");
        listDialog.setItems(items, new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                connect(bluetoothDeviceList.get(which).getAddress());
                ToastUtils.showMsg(bluetoothDeviceList.get(which).getName() + " " + bluetoothDeviceList.get(which).getAddress());
            }
        });
        listDialog.show();
    }

    /**
     * 判断蓝牙是否连接
     */
    public boolean isConnection() {
//        int a2dp = adapter.getProfileConnectionState(BluetoothProfile.A2DP);
//        int headset = adapter.getProfileConnectionState(BluetoothProfile.HEADSET);
//        int health = adapter.getProfileConnectionState(BluetoothProfile.HEALTH);
//        return adapter != null && (a2dp == BluetoothAdapter.STATE_CONNECTED ||
//                headset == BluetoothAdapter.STATE_CONNECTED ||
//                health == BluetoothAdapter.STATE_CONNECTED);
        return isConnection;
    }

    //注册监听蓝牙连接状态
    public void registerBoradcastReceiver(Activity activity, final BluetoothListener listener) {
        IntentFilter filterFound = new IntentFilter(BluetoothDevice.ACTION_FOUND);
        IntentFilter filterFinished = new IntentFilter(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
        IntentFilter stateChangeFilter = new IntentFilter(BluetoothAdapter.ACTION_STATE_CHANGED);
        IntentFilter connectedFilter = new IntentFilter(BluetoothDevice.ACTION_ACL_CONNECTED);
        IntentFilter disConnectedFilter = new IntentFilter(BluetoothDevice.ACTION_ACL_DISCONNECTED);
        IntentFilter pairingRequestFilter = new IntentFilter(BluetoothReceiver.PAIRING_REQUEST);
        activity.registerReceiver(stateChangeReceiver, stateChangeFilter);
        activity.registerReceiver(stateChangeReceiver, connectedFilter);
        activity.registerReceiver(stateChangeReceiver, disConnectedFilter);
        activity.registerReceiver(stateChangeReceiver, filterFound);
        activity.registerReceiver(stateChangeReceiver, filterFinished);
        activity.registerReceiver(stateChangeReceiver, pairingRequestFilter);
        stateChangeReceiver.setListener(new BluetoothListener() {
            @Override
            public void bluetoothList(List<BluetoothDevice> deviceList) {
                listener.bluetoothList(deviceList);
            }

            @Override
            public void connection(boolean status) {
                listener.connection(status);
                isConnection = status;
            }
        });
    }

    /**
     * 取消注册广播
     */
    public void unregisterReceiver(Activity activity) {
        activity.unregisterReceiver(stateChangeReceiver);
    }

    /**
     * 发现蓝牙
     */
    public void doDiscovery() {
        if (adapter.isDiscovering()) {
            //如果正在发现,就取消发现
            adapter.cancelDiscovery();
        }
        adapter.startDiscovery();
    }

    /**
     * @return 是否蓝牙已准备好
     */
    public boolean isAdapterReady() {
        return (adapter != null) && (adapter.isEnabled());
    }

    /**
     * 连接蓝牙
     */
    public void setupConnector(BluetoothDevice connectedDevice) {
        if (connector != null) {
            stopConnection();
        }
        if (isAdapterReady() && connector == null) {
            stopConnection();
            try {
                String emptyName = "<New device>";
                DeviceData data = new DeviceData(connectedDevice, emptyName);
                connector = new DeviceConnector(data, mHandler);
                connector.connect();
            } catch (IllegalArgumentException e) {
                LogX.w("setupConnector failed: " + e.getMessage());
            }
        }
    }

    private void stopConnection() {
        if (connector != null) {
            connector.stop();
            isConnection = false;
            connector = null;
            deviceName = null;
        }
    }

    public interface MessageCallback {
        void bluttoothMessage(int[] data);
    }
}
